package com.ass.freedom.net.handler;

import com.alibaba.fastjson.JSONObject;
import com.ass.freedom.net.boot.NettyBootstrapClient;
import com.ass.freedom.net.handler.FMessageHandler;
import com.ass.freedom.net.protocol.FMTraits;
import com.ass.freedom.net.protocol.FMessage;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.EventLoop;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.ScheduledFuture;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

/**
 * @author syq
 * @date 2019/12/24
 */
@Slf4j
@ChannelHandler.Sharable
public class ClientHandler extends FMessageHandler {

    public static final AttributeKey<ClientOps> CLIENT = AttributeKey.valueOf("TcpClient");

    public static final AttributeKey<ScheduledFuture<?>> SCHEDULE = AttributeKey.valueOf("schedule");

    private final EventLoop pingEventLoop;

    private final int pingInterval = 25;


    public ClientHandler(EventLoop pingEventLoop) {
        this.pingEventLoop = pingEventLoop;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel chnl = ctx.channel();
        ScheduledFuture<?> schedule = pingEventLoop.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                log.info("send ping");
                FMessage ping = FMessage.buildPing();
                chnl.writeAndFlush(ping);
            }
        }, 1, pingInterval, TimeUnit.SECONDS);
        chnl.attr(SCHEDULE).set(schedule);

        log.info("tcp client connected. remote address:{}", chnl.remoteAddress().toString());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel chnl = ctx.channel();
        ScheduledFuture<?> future = chnl.attr(SCHEDULE).getAndSet(null);
        if(null != future){
            future.cancel(true);
        }
        chnl.attr(CLIENT).set(null);
        log.info("tcp client closed. remote address:{}", chnl.remoteAddress().toString());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("", cause.getMessage());
        ctx.close();
    }

    @Override
    protected void onPong(ChannelHandlerContext ctx, FMessage msg) throws Exception {
        //服务器返回
        log.info("tcp clinet on pong ");
    }

    @Override
    protected void onPush(ChannelHandlerContext ctx, FMessage msg) throws Exception {
        super.onPush(ctx, msg);
    }

    @Override
    protected void onResponse(ChannelHandlerContext ctx, FMessage msg) throws Exception {
        ClientOps client = ctx.channel().attr(CLIENT).get();
        if(null == client) {
            return;
        }
        client.onResponse(msg);
    }


}
